package com.information.service;

import com.information.entity.User;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.List;

@Service
public class RedisService {

    private final StringRedisTemplate stringRedisTemplate;
    private final ObjectMapper objectMapper;

    @Autowired
    public RedisService(StringRedisTemplate stringRedisTemplate,
                        ObjectMapper objectMapper) {
        this.stringRedisTemplate = stringRedisTemplate;
        this.objectMapper = objectMapper;
    }

    /**
     * 字符串操作
     * @param key
     * @param value
     */
    public void setString(String key, String value) {
        stringRedisTemplate.opsForValue().set(key, value);
    }

    public String getString(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }

    /**
     * 检查连接
     * @return Boolean
     */
    public Boolean testConnection() {
        try {
            return stringRedisTemplate.hasKey("test");
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * ping测试方法
     * @return String
     */
    public String ping() {
        try {
            return stringRedisTemplate.getConnectionFactory()
                    .getConnection().ping();
        } catch (Exception e) {
            return "PONG failed: " + e.getMessage();
        }
    }

    /**
     * 添加连接信息获取
     * @return String
     */
    public String getConnectionInfo() {
        try {
            return "Redis连接正常";
        } catch (Exception e) {
            return "获取信息失败: " + e.getMessage();
        }
    }

    /**
     * 用户缓存相关方法
     * @param user
     */
    public void cacheUser(User user) {
        try {
            String userJson = objectMapper.writeValueAsString(user);
            stringRedisTemplate.opsForValue().set(getUserCacheKey(user.getId()), userJson, Duration.ofHours(24));
        } catch (Exception e) {
            System.err.println("缓存用户失败: " + e.getMessage());
        }
    }

    /**
     * 从缓存中获取用户
     * @param userId
     * @return User
     */
    public User getCachedUser(Long userId) {
        try {
            String userJson = stringRedisTemplate.opsForValue().get(getUserCacheKey(userId));
            if (userJson != null) {
                return objectMapper.readValue(userJson, User.class);
            }
        } catch (Exception e) {
            System.err.println("获取缓存用户失败: " + e.getMessage());
        }
        return null;
    }

    /**
     * 从缓存中删除用户
     * @param userId
     */
    public void evictUser(Long userId) {
        try {
            String key = getUserCacheKey(userId);
            Boolean deleted = stringRedisTemplate.delete(key);
        } catch (Exception e) {
            System.err.println("清除用户缓存失败: " + e.getMessage());
        }
    }

    /**
     * 通过用户名删除缓存
     * @param username
     */
    public void evictUserByUsername(String username) {
        try {
            String key = getUsernameCacheKey(username);
            Boolean deleted = stringRedisTemplate.delete(key);
        } catch (Exception e) {
            System.err.println("清除用户名缓存失败: " + e.getMessage());
        }
    }

    /**
     * 按用户名缓存用户
     * @param user
     */
    public void cacheUserByUsername(User user) {
        try {
            String userJson = objectMapper.writeValueAsString(user);
            stringRedisTemplate.opsForValue().set(getUsernameCacheKey(user.getUsername()), userJson, Duration.ofHours(24));
        } catch (Exception e) {
            System.err.println("按用户名缓存用户失败: " + e.getMessage());
        }
    }

    /**
     * 按用户名获取缓存用户
     * @param username
     * @return User
     */
    public User getCachedUserByUsername(String username) {
        try {
            String userJson = stringRedisTemplate.opsForValue().get(getUsernameCacheKey(username));
            if (userJson != null) {
                return objectMapper.readValue(userJson, User.class);
            }
        } catch (Exception e) {
            System.err.println("按用户名获取缓存用户失败: " + e.getMessage());
        }
        return null;
    }

    /**
     * 缓存所有用户列表
     * @param users
     */
    public void cacheAllUsers(List<User> users) {
        try {
            String usersJson = objectMapper.writeValueAsString(users);
            stringRedisTemplate.opsForValue().set(getAllUsersCacheKey(), usersJson, Duration.ofMinutes(30));
        } catch (Exception e) {
            System.err.println("缓存用户列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取所有缓存用户
     * @return List<User>
     */
    public List<User> getCachedAllUsers() {
        try {
            String usersJson = stringRedisTemplate.opsForValue().get(getAllUsersCacheKey());
            if (usersJson != null) {
                return objectMapper.readValue(usersJson, new TypeReference<List<User>>() {});
            }
        } catch (Exception e) {
            System.err.println("获取缓存用户列表失败: " + e.getMessage());
        }
        return null;
    }

    /**
     * 清楚所有缓存用户
     */
    public void evictAllUsers() {
        try {
            String key = getAllUsersCacheKey();
            Boolean deleted = stringRedisTemplate.delete(key);
        } catch (Exception e) {
            System.err.println("清除用户列表缓存失败: " + e.getMessage());
        }
    }

    /**
     * 缓存键生成方法
     * @param userId
     * @return String
     */
    private String getUserCacheKey(Long userId) {
        return "user:id:" + userId;
    }

    private String getUsernameCacheKey(String username) {
        return "user:username:" + username;
    }

    private String getAllUsersCacheKey() {
        return "users:all";
    }
}